package org.example.day11;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 4.1.8.2 实现生产者/消费者 多对对交替打印
 *      ②将condition.signal() 修改为 condition.signalAll() 解决假死问题.
 *       但是notifyAll也会形成多次唤醒调用同样方法的线程，经过判断继续等待
 */
public class MyThread3 {
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private boolean hasValue = false;
    public void set(){
        try {
            lock.lock();
            while(hasValue == true){
                System.out.println("有可能★★连续");
                condition.await();
            }
            System.out.println("打印★");
            hasValue = true;
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void get(){
        try {
            lock.lock();
            while(hasValue == false){
                System.out.println("有可能☆☆连续");
                condition.await();
            }
            System.out.println("打印☆");
            hasValue = false;
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        MyThread3 m3 = new MyThread3();
        Thread3A[] tas = new Thread3A[10];
        Thread3B[] tbs = new Thread3B[10];
        for (int i = 0; i < 10; i++) {
            tas[i] = new Thread3A(m3);
            tbs[i] = new Thread3B(m3);
            tas[i].start();
            tbs[i].start();
        }
    }
}

class Thread3A extends Thread{
    private MyThread3 m3;

    public Thread3A(MyThread3 m3) {
        this.m3 = m3;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            m3.set();
        }
    }
}

class Thread3B extends Thread{
    private MyThread3 m3;

    public Thread3B(MyThread3 m3) {
        this.m3 = m3;
    }

    @Override
    public void run() {
        for (int i = 0; i <1000; i++) {
            m3.get();
        }
    }
}